package com.ethink.warehouse.facade.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ethink.framework.common.constant.CommonRespCode;
import com.ethink.framework.common.exception.BusinessException;
import com.ethink.framework.common.web.context.SPRequestContextHolder;
import com.ethink.id.generator.IdGenerator;
import com.ethink.warehouse.api.MateInventoryOtherInLogFacade;
import com.ethink.warehouse.api.enums.MateInventoryOtherInLogOrderStatusEnum;
import com.ethink.warehouse.api.info.MateInventoryOtherInLogDetailInfo;
import com.ethink.warehouse.api.info.MateInventoryOtherInLogInfo;
import com.ethink.warehouse.api.info.MateInventoryOtherInLogModeInfo;
import com.ethink.warehouse.api.request.MateInventoryOtherInLogAddRequest;
import com.ethink.warehouse.api.request.MateInventoryOtherInLogQueryRequest;
import com.ethink.warehouse.api.request.MateInventoryOtherInLogUpdateRequest;
import com.ethink.warehouse.api.response.MateInventoryOtherInLogAddResponse;
import com.ethink.warehouse.api.response.MateInventoryOtherInLogDetailResponse;
import com.ethink.warehouse.api.response.MateInventoryOtherInLogUpdateResponse;
import com.ethink.warehouse.common.entity.MateInventory;
import com.ethink.warehouse.common.entity.MateInventoryOtherInLog;
import com.ethink.warehouse.common.entity.MateInventoryOtherInLogDetail;
import com.ethink.warehouse.common.mapper.MateInventoryOtherInLogDetailMapper;
import com.ethink.warehouse.manager.MateInventoryManager;
import com.ethink.warehouse.service.MateInventoryOtherInLogDetailService;
import com.ethink.warehouse.service.MateInventoryOtherInLogService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 其他入库 Facade接口实现
 *
 * @author default
 * @date 2023-02-09
 */
@RestController
@Slf4j
@RequestMapping("warehouse-service/facade/v1/mateInventoryOtherInLog")
public class MateInventoryOtherInLogFacadeImpl implements MateInventoryOtherInLogFacade {

    @Autowired
    private MateInventoryOtherInLogService mateInventoryOtherInLogService;

    @Autowired
    private IdGenerator idGenerator;

    @Autowired
    private MateInventoryOtherInLogDetailService mateInventoryOtherInLogDetailService;

    @Autowired
    private MateInventoryManager mateInventoryManager;

    @Autowired
    private MateInventoryOtherInLogDetailMapper mateInventoryOtherInLogDetailMapper;

    @Override
    public Page<MateInventoryOtherInLogInfo> queryMateInventoryOtherInLog(MateInventoryOtherInLogQueryRequest request) {
        return mateInventoryOtherInLogService.queryMateInventoryOtherInLog(request);
    }

    @Override
    public MateInventoryOtherInLogDetailResponse getMateInventoryOtherInLogById(Long mateInventoryOtherInLogId) {
        return mateInventoryOtherInLogService.getMateInventoryOtherInLogById(mateInventoryOtherInLogId);
    }

    @Override
    public List<MateInventoryOtherInLogInfo> listMateInventoryOtherInLog(MateInventoryOtherInLogQueryRequest request) {
        return mateInventoryOtherInLogService.listMateInventoryOtherInLog(request);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public MateInventoryOtherInLogAddResponse addMateInventoryOtherInLog(MateInventoryOtherInLogAddRequest request) {
        request.setOrderNo(idGenerator.ork());
        request.setOrderStatus(MateInventoryOtherInLogOrderStatusEnum.S2.getIntValue());
        request.setCreateUserCode(SPRequestContextHolder.getCurrentSystemUserLoginName());
        request.setCreateUserName(SPRequestContextHolder.getCurrentSystemUserRealName());
        // 添加明细表
        List<MateInventoryOtherInLogDetailInfo> childrenRequestList = request.getItems();
        List<MateInventoryOtherInLogDetail> childrenList = new ArrayList<>();
        childrenRequestList.forEach(item -> {
            MateInventoryOtherInLogDetail children = new MateInventoryOtherInLogDetail();
            BeanUtil.copyProperties(item, children, true);
            children.setOrderNo(request.getOrderNo());
            children.setCreateUser(request.getCreateUserName());
            children.setIsDeleted(Boolean.FALSE);
            children.setCreateTime(LocalDateTime.now());
            children.setUpdateTime(LocalDateTime.now());
            children.setCostPrice(item.getExceptCostPrice());
            childrenList.add(children);
        });
        Boolean aBoolean = mateInventoryOtherInLogDetailService.addMateInventoryOtherInLogDetailList(childrenList);
        if (!aBoolean) {
            throw new RuntimeException("新增明细失败");
        }
        MateInventoryOtherInLogAddResponse mateInventoryOtherInLogAddResponse = mateInventoryOtherInLogService.addMateInventoryOtherInLog(request);
        if (ObjectUtils.isEmpty(mateInventoryOtherInLogAddResponse)) {
            throw new RuntimeException("新增失败");
        }
        return mateInventoryOtherInLogAddResponse;
    }

    @Override
    public MateInventoryOtherInLogUpdateResponse updateMateInventoryOtherInLog(MateInventoryOtherInLogUpdateRequest request) {
        return mateInventoryOtherInLogService.updateMateInventoryOtherInLog(request);
    }

    @Override
    public Boolean deleteMateInventoryOtherInLog(Long mateInventoryOtherInLogId) {
        return mateInventoryOtherInLogService.deleteMateInventoryOtherInLog(mateInventoryOtherInLogId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean mateInventoryOtherInLogPass(Long mateInventoryOtherInLogId) {
        MateInventoryOtherInLog changeLog = mateInventoryOtherInLogService.selectMateInventoryOtherInLogById(mateInventoryOtherInLogId);
        if (!MateInventoryOtherInLogOrderStatusEnum.S2.eq(changeLog.getOrderStatus())) {
            throw new BusinessException(CommonRespCode.SYSTEM_ERR, "当前订单状态无法审批通过");
        }
        mateInventoryOtherInLogService.mateInventoryOtherInLogPass(mateInventoryOtherInLogId);
        List<MateInventoryOtherInLogDetail> changeLogDetails = mateInventoryOtherInLogDetailMapper.selectList(
                new LambdaQueryWrapper<MateInventoryOtherInLogDetail>()
                        .eq(MateInventoryOtherInLogDetail::getOrderNo, changeLog.getOrderNo())
        );
        Map<Long, MateInventory> map = mateInventoryManager.otherIn(changeLog, changeLogDetails);
        for (Map.Entry<Long, MateInventory> entry : map.entrySet()) {
            mateInventoryOtherInLogDetailMapper.update(null, new LambdaUpdateWrapper<MateInventoryOtherInLogDetail>()
                    .eq(MateInventoryOtherInLogDetail::getId, entry.getKey())
                    .set(MateInventoryOtherInLogDetail::getPurchaseCode, entry.getValue().getPurchaseCode())
                    .set(MateInventoryOtherInLogDetail::getMateInventoryId, entry.getValue().getId())
            );
        }
        return mateInventoryOtherInLogService.mateInventoryOtherInLogPass(mateInventoryOtherInLogId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean mateInventoryOtherInLogRefuse(Long mateInventoryOtherInLogId) {
        MateInventoryOtherInLog mateInventoryOtherInLog = mateInventoryOtherInLogService.selectMateInventoryOtherInLogById(mateInventoryOtherInLogId);
        if (!MateInventoryOtherInLogOrderStatusEnum.S2.eq(mateInventoryOtherInLog.getOrderStatus())) {
            throw new BusinessException(CommonRespCode.SYSTEM_ERR, "当前订单状态无法审批拒绝");
        }
        return mateInventoryOtherInLogService.mateInventoryOtherInLogRefuse(mateInventoryOtherInLogId);
    }

    @Override
    public Page<MateInventoryOtherInLogModeInfo> queryMateInventoryOtherInLogMode(MateInventoryOtherInLogQueryRequest request) {
        return mateInventoryOtherInLogService.queryMateInventoryOtherInLogMode(request);
    }
}